#lang racket


(provide λid
         cλ
         range
         range-n
         range-step
         random-interval)


(define λid (λ (x) x))

(define cλ
  (λ args
    (λ cargs
      (apply (first args) (append (rest args) cargs)))))

(define range
  (letrec ((range-aux (λ (a b acc)
                        (if (> a b)
                            acc
                            (range-aux a (- b 1) (cons b acc))))))
           (case-lambda
             ((n)
              (range-aux 0 (- n 1) '()))
             ((a b)
              (range-aux a (- b 1) '())))))

(define (range-n a b n)
  (define (aux i)
    (if (>= i n)
        (list)
        (cons
         (/ (+ (* a (- n i)) (* i b)) n)
         (aux (+ i 1)))))
  (aux 0))

(define (range-step a b s)
  (define (range-aux-step a b acc)
    (if (>= a b)
        (reverse acc)
        (range-aux-step (+ a s) b (cons a acc))))
  (range-aux-step a b '()))

(define (enumerate a b s)
  (if (> a b)
      (list)
      (cons a (enumerate (+ a s) b s))))

(define (random-interval x0 x1)
  (+ x0 (* (- x1 x0) (random))))